#ifndef _REJILLA_H_
#define _REJILLA_H_
#include <string.h>
#include <iostream>
#include <fstream>

using namespace std;
 
/**
 *La clase Rejilla representa un tablero en el que se desarrolla el juego de la vida de Conway.
 *Esta rejilla puede tener distintos valores de ancho y alto. Ademas puede contener contener
 *subsectores cuadrados de los cuales pueden especifiarse sus dimensiones.
 *En este caso una celda del tablero solo puede tener dos estado, viva o muerta.
 *Las reglas del juego que quieran aplicarse no se contemplan en este objeto.
 *@author Roman Jimenez de Andres.
 *@author Luis Ciudad Garcia.
 *@date 02/09/2009.
 */


class Rejilla{
	private:
        
		unsigned int _ancho;     /**< Ancho o columnas de la rejilla. */
        unsigned int _alto;      /**< Alto o filas de la rejilla. */
        unsigned int _tamSector; /**< Dimensiones tanto alto como ancho de los subsectores. */
		int **_matriz;           /**< Matriz con cada una de las celdas del tablero. */
        
        /**
         *Este metodo devuelve una Rejilla cuadrada de las dimensiones indicadas por el tercer
         *parametro y empezando en la posicion de la matriz indicada por los dos primeros parametros.
         *@author Roman Jimenez de Andres.
         *@author Luis Ciudad Garcia.
         *@date 02/09/2009.
         *@param fila Fila en la que se colocara el primer elemento del sector devuelto.
         *@param columna Columna en la que se situara el primer elemento del sector devuelto.
         *@param tamano Alto y ancho del sector devuelto.
         *@return Rejilla de las dimensiones especificadas, a partir de la posicion indicada 
         *y con las mismas dimensiones de sector que la Rejilla original.
         */
        Rejilla sector(unsigned int, unsigned int, unsigned int);
		
	public:

        /**
         *Constructor vacio de la clase Rejilla. Devuelve una Rejilla de 0 filas, 0 columnas, vacia y 
         *con dimensiones de sector 0.
         *@author Roman Jimenez de Andres
         *@author Luis Ciudad Garcia
         *@date 02/09/2009
         *@return Rejilla de 0 filas, 0 columnas, vacia y con dimensiones de sector 0.
         */
		Rejilla();

        /**
         *Constructor de la clase Rejilla. Hace una copia de la instancia de Rejilla pasada como parametro.
         *@author Roman Jimenez de Andres
         *@author Luis Ciudad Garcia
         *@date 02/09/2009
         *@param copia Rejilla de la que quieren copiarse sus caracteristicas.
         *@return Rejilla de las mismas caracteristicas que la que se pasa por parametro.
         */
        Rejilla(const Rejilla&);

        /**
         *Constructor de la clase Rejilla. Crea una Rejilla a partir del fichero indicado asignando
         *las dimensiones de sector que se pasan por parametro. El formato del fichero debe ser el siguiente:
         *En la primera linea el ancho, en la siguiente linea el alto y en sucesivas lineas cada una de las celdas
         *que componen la matriz separadas por espacios en blanco y separando las filas por salto de linea.
         *Las celdas vivas se representaran con un 1 y las muertas con un 0.
         *@author Roman Jimenez de Andres
         *@author Luis Ciudad Garcia
         *@date 02/09/2009
         *@param filename Nombre del fichero que contiene la especificacion de la Rejilla que se quiere crear.
         *@param tamSector Dimensiones de sector a aplicar a la nueva Rejilla.
         *@return Rejilla definida en el fichero y con dimensiones de sector acordes a los parametros.
         */
		Rejilla(string, unsigned int);

        /**
         *Constructor de la clase Rejilla. Crea una Rejilla con el numero de filas y el numero de columnas
         *indicado en los parametros con unas dimensiones de sector tambien indicadas en los parametros
         *y con todas las celdas inicializadas en el estado "muerta".
         *@author Roman Jimenez de Andres
         *@author Luis Ciudad Garcia
         *@date 02/09/2009
         *@param filas Numero de filas de la Rejilla.
         *@param columnas Numero de columnas de la Rejilla.
         *@param tamSector Dimensiones de los sectores.
         *@return Rejilla de dimensiones y dimensiones de sector indicadas en los parametros con todas las
         *celdas en el estado "muerta".
         */
        Rejilla(unsigned int, unsigned int, unsigned int);

        /**
         *Constructor de la clase Rejilla. Crea una Rejilla con el numero de filas y el numero de columnas
         *indicado en los parametros con unas dimensiones de sector tambien indicadas en los parametros
         *y con las celdas al mismo valor que las de la matriz. Al tratarse de una matriz de enteros, un 1
         *es considerado una celda "viva" y un 0 una celda "muerta".
         *@author Roman Jimenez de Andres
         *@author Luis Ciudad Garcia
         *@date 02/09/2009
         *@param filas Numero de filas de la Rejilla.
         *@param columnas Numero de columnas de la Rejilla.
         *@param tamSector Dimensiones de los sectores.
         *@param matriz Valores de las celdas de la nueva Rejilla
         *@return Rejilla de dimensiones y dimensiones de sector indicadas en los parametros y con las 
         *celdas al mismo valor que las de la matriz pasada por los parametros.
         */
        Rejilla(unsigned int, unsigned int, unsigned int, int**);
        

        /**
         *Observador del miembro privado que mantiene el ancho o numero de columnas de la Rejilla.
         *@author Roman Jimenez de Andres
         *@author Luis Ciudad Garcia
         *@date 02/09/2009
         *@return Ancho o numero de columnas de la Rejilla.
         */        
		int getAncho();

        /**
         *Observador del miembro privado que mantiene el alto o numero de filas de la Rejilla.
         *@author Roman Jimenez de Andres
         *@author Luis Ciudad Garcia
         *@date 02/09/2009
         *@return Alto o numero de filas de la Rejilla.
         */
		int getAlto();

        /**
         *Observador del miembro privado que mantiene las dimensiones de los sectores de la Rejilla.
         *@author Roman Jimenez de Andres
         *@author Luis Ciudad Garcia
         *@date 02/09/2009
         *@return Dimensiones de los sectores de la Rejilla.
         */
        int getTamSector();

        /**
         *Observador del miembro privado que mantiene el estado de las celdas de la Rejilla.
         *@author Roman Jimenez de Andres
         *@author Luis Ciudad Garcia
         *@date 02/09/2009
         *@return Un vector de enteros con todas las celdas de la Rejilla ordenados por la fila.
         *Al devolver enteros, se considera una celda "muerta" como un 0 y una "viva" como un 1.
         */
        int* getMatriz();

        /**
         *Observador de cada una de las celdas que componen la Rejilla.
         *@author Roman Jimenez de Andres
         *@author Luis Ciudad Garcia
         *@date 02/09/2009
         *@param fila Fila en la que se encuentra la celda a recuperar.
         *@param columna Columna en la que se encuentra la celda a recuperar.
         *@return Un entero con el valor de la celda en la posicion indicada por los parametros.
         *Al devolver un entero, se considera una celda "muerta" como un 0 y una "viva" como un 1.
         */
        int getElemento(unsigned int, unsigned int);

        /**
         *Este metodo se encarga de poner la celda indicada al estado que dictan los parametros.
         *@author Roman Jimenez de Andres
         *@author Luis Ciudad Garcia
         *@date 02/09/2009
         *@param fila Fila en la que se encuentra la celda.
         *@param columna Columna en la que se encuentra la celda.
         *@param estado Nuevo estado en que se pondra la celda. Al tratar con enteros 0 es el estado "muerta"
         * y 1 el estado "viva".
         */
        void setElemento(unsigned int, unsigned int,int);

        /**
         *Este metodo cambia el estado de una celda. Si el estado de la celda es "muerta" lo pone en "viva" y viceversa.
         *Tambien devuelve el nuevo estado de la celda tras el cambio.
         *@author Roman Jimenez de Andres
         *@author Luis Ciudad Garcia
         *@date 02/09/2009
         *@param fila Fila en la que se encuentra la celda.
         *@param columna Columna en la que se encuentra la celda.
         *@return Nuevo estado en que se encuentra la celda.
         */       
		int flipElemento(unsigned int, unsigned int);

        /**
         *Este metodo cambia el estado de todas las celdas al estado indicado por los parametros.
         *@author Roman Jimenez de Andres
         *@author Luis Ciudad Garcia
         *@date 02/09/2009
         *@param estado Estado que pasaran a tener todas las celdas. Al tratarse de un entero consideramos
         *un 0 como estado "muerta" y 1 como "viva".
         */  
        void ponerTodo(int);

        /**
         *Este metodo cambia el estado de todas las celdas al estado contrario, creando la Rejilla inversa.
         *@author Roman Jimenez de Andres
         *@author Luis Ciudad Garcia
         *@date 02/09/2009
         */
        void invertir();

        /**
         *Este metodo cambia la Rejilla aleatoreamente poniendo cada celda a un estado al azar.
         *@author Roman Jimenez de Andres
         *@author Luis Ciudad Garcia
         *@date 02/09/2009
         */
        void aleatoria();

        /**
         *Este metodo devuelve la cantidad de sectores que tiene una Rejilla a lo alto. Este numero de sectores
         *depende de la cantidad de filas de la matriz asi com de las dimensiones de sector que posee la Rejilla.
         *Tambien se cuentan los sectores que no esten completamente contenidos dentro de la matriz.
         *@author Roman Jimenez de Andres
         *@author Luis Ciudad Garcia
         *@date 02/09/2009
         *@return Numero de sectores que tiene una Rejilla a lo alto.
         */
        int numPartesAlto();
        /**
         *Este metodo devuelve la cantidad de sectores que tiene una Rejilla a lo ancho. Este numero de sectores
         *depende de la cantidad de columnas de la matriz asi com de las dimensiones de sector que posee la Rejilla.
         *Tambien se cuentan los sectores que no esten completamente contenidos dentro de la matriz.
         *@author Roman Jimenez de Andres
         *@author Luis Ciudad Garcia
         *@date 02/09/2009
         *@return Numero de sectores que tiene una Rejilla a lo ancho.
         */
        int numPartesAncho();

        /**
         *Este metodo devuelve todos los sectores contenidos en una Rejilla que a su vez tambien son Rejillas.
         *La cantidad de sectores devueltos depende de las dimensiones de la Rejilla y de las dimensiones
         *de sector que esta posea. Los sectores devueltos son cuadrados con las mismas dimensiones que las
         *dimensiones de sector de la Rejilla original. Si un sector no esta completamente contenido en la
         *Rejilla original las celdas que no estan contenidas se devuelven con el estado "muerta". Las
         *dimensiones de sector de cada sector son las mismas que las de la Rejilla original, es decir,
         *los sectores generados solo tiene un subsector. Ademas se modifica el parametro pasado por referencia
         *con el numero de sectores devueltos en el vector de Rejillas.
         *@author Roman Jimenez de Andres
         *@author Luis Ciudad Garcia
         *@date 02/09/2009
         *@param sectores Parametro por referencia que se cambia al numero de sectores que van a ser devueltos.
         *@return Vector de Rejillas siendo cada una de ellas uno de los sectores de la Rejilla original.
         */
        Rejilla* particiones(int &);

        /**
         *Este metodo cambia un sector completo de la Rejilla original empezando por la posicion indicada
         *por los parametros y poniendo las celdas a los estados indicados en esos mismos parametros.
         *@author Roman Jimenez de Andres
         *@author Luis Ciudad Garcia
         *@date 02/09/2009
         *@param fila Fila en la que se encuentra la celda de inicio.
         *@param columna Columna en la que se encuentra la celda de inicio.
         *@param estados Vector que contiene los nuevos estados de las celdas que se van a modificar.
         *Al tratarse de enteros, consideramos un 0 como el estado "muerta" y un 1 como el estado "viva".
         */
        void setSector(unsigned int, unsigned int, int*);
        		
		int mapearRejilla(Rejilla &, int, int);
        
        /**
         *Este metodo vuelca la informacion de la Rejilla a un fichero para poder ser recuperada mas tarde.
         *En el fichero no se guardan las dimensiones de sector de la Rejilla. El formato del fichero es el siguiente:
         *En la primera linea el ancho, en la siguiente linea el alto y en sucesivas lineas cada una de las celdas
         *que componen la matriz separadas por espacios en blanco y separando las filas por salto de linea.
         *Las celdas vivas se representaran con un 1 y las muertas con un 0.
         *@author Roman Jimenez de Andres
         *@author Luis Ciudad Garcia
         *@date 02/09/2009
         *@param filename Nombre del archivo en el que se guardara la informacion de la Rejilla.
         */
        void volcar(string); 
		
        /**
         *Este metodo representa mediante la consola la Rejilla.
         *Las celdas vivas se representaran con un 1 y las muertas con un 0.
         *@author Roman Jimenez de Andres
         *@author Luis Ciudad Garcia
         *@date 02/09/2009
         */
        void drawan();
	};

#endif


